#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    initUI();
    initSerialPort();
    initTimer();

    gCmdType = -1;
}

MainWindow::~MainWindow()
{
    delete ui;
}

/*
 * 函数功能：完成对串口助手界面的初始化
 */
void MainWindow::initUI()
{
    gSerialSwitchFlg = false;
    gSetting = new QSettings("./Setting.ini", QSettings::IniFormat);

    //设置端口号波特率
    // ui->cboBaudrate->addItem(QString("1200"),QSerialPort::Baud1200);
    // ui->cboBaudrate->addItem(QString("2400"),QSerialPort::Baud2400);
    // ui->cboBaudrate->addItem(QString("4800"),QSerialPort::Baud4800);
    // ui->cboBaudrate->addItem(QString("9600"),QSerialPort::Baud9600);
    // ui->cboBaudrate->addItem(QString("19200"),QSerialPort::Baud19200);
    // ui->cboBaudrate->addItem(QString("38400"),QSerialPort::Baud38400);
    // ui->cboBaudrate->addItem(QString("57600"),QSerialPort::Baud57600);
    ui->cboBaudrate->addItem(QString("115200"),QSerialPort::Baud115200);

    //设置端口数据位数
    ui->cboDataBit->addItem("8",QSerialPort::Data8);
    // ui->cboDataBit->addItem("7",QSerialPort::Data7);
    // ui->cboDataBit->addItem("6",QSerialPort::Data6);
    // ui->cboDataBit->addItem("5",QSerialPort::Data5);

    //设置端口校验方式
    ui->cboParity->addItem("None",QSerialPort::NoParity);
    // ui->cboParity->addItem("Odd",QSerialPort::OddParity);
    // ui->cboParity->addItem("Even",QSerialPort::EvenParity);

    //设置端口停止位
    ui->cboStopBit->addItem("1",QSerialPort::OneStop);
    // ui->cboStopBit->addItem("1.5",QSerialPort::OneAndHalfStop);
    // ui->cboStopBit->addItem("2",QSerialPort::TwoStop);

    //设置端口流控制
    ui->cboFlowContral->addItem("None",QSerialPort::NoFlowControl);
    // ui->cboFlowContral->addItem("RTS/CTS",QSerialPort::HardwareControl);
    // ui->cboFlowContral->addItem("XON/XOFF",QSerialPort::SoftwareControl);

    ui->btnSend->setDisabled(true);

}
/*
 * 函数功能：串口设置的初始化
 */
void MainWindow::initSerialPort()
{
    if(!gSerialSwitchFlg)
    {
        QStringList newPortStringList;
        static QStringList oldPortStringList;

        const auto infos = QSerialPortInfo::availablePorts();
        for (const QSerialPortInfo &info : infos)
        {
            newPortStringList += info.portName();
        }
        //更新串口号
        if(newPortStringList.size() != oldPortStringList.size())
        {
            oldPortStringList = newPortStringList;
            ui->cboPortName->clear();
            ui->cboPortName->addItems(oldPortStringList);
        }

        // 读取上次的设置
        ui->cboPortName->setCurrentText(gSetting->value("LastSelectSerialPort").toString());
        ui->cboBaudrate->setCurrentText(gSetting->value("LastSelectSerialBaud").toString());
    }
}
/*
 * 函数功能：初始化定时器
 */
void MainWindow::initTimer()
{
    gSerialPortTimer = startTimer(1000, Qt::CoarseTimer);
}
/*
 * 函数功能：定时更新当前系统中的串口号
 */
void MainWindow::timerUpdateSerialPort()
{
    initSerialPort();
}
/*
 * 函数功能：接收串口发出数据将其显示到界面上
 */
void MainWindow::receiveData()
{
    QByteArray data = gSerialPort->readAll();

    //QString strText = QString(data);
    QString strText = data.toHex();


    ui->RecveeiveplainTextEdit->appendPlainText(strText);
    // 命令解析
    switch(gCmdType)
    {
    case 4:
    {
        QString cookStr;

        cookStr.prepend(data);

        QString content = "NDT Firmware Ver:" + cookStr;

        ui->DecodplainTextEdit->appendPlainText(content);
        gCmdType = -1;
    }break;
    case 5:
    {
        uint16_t bat_vol = 0;
        uint16_t ntc_vol = 0;
        uint8_t bat_percent = 0;
        uint8_t ntc_temperature = 0;

        bat_vol = (data[1]<<8) + data[0];
        ntc_vol = (data[4]<<8) + data[3];
        bat_percent = data[2];
        ntc_temperature = data[5];
        QString content = "电池ADC:" + QString::number(bat_vol, 10) +
                          ", 电量" + QString::number(bat_percent, 10) +
                          "% ,NTC ADC:" + QString::number(ntc_vol, 10) +
                          ", NTC 温度:" + QString::number(ntc_temperature, 10) + "℃";

        ui->DecodplainTextEdit->appendPlainText(content);
        gCmdType = -1;
    }break;
    case 10:
    {
        QString cookStr = data.toHex();

        QString content = "本机密钥:" + cookStr;

        ui->DecodplainTextEdit->appendPlainText(content);
        gCmdType = -1;
    }break;
    case 14://key
    {//000000c8
        uint8_t cook[4] = {0};
        cook[0] = static_cast<uint>(data.at(0));
        cook[1] = static_cast<uint>(data.at(1));
        cook[2] = static_cast<uint>(data.at(2));
        cook[3] = static_cast<uint>(data.at(3));

        //uint16_t head_val = (cook[0]<<8) + cook[1];

        uint16_t key_val =  (cook[2]<<8) + cook[3];
        QString content = "按键阈值:" + QString::number(key_val, 10);

        ui->DecodplainTextEdit->appendPlainText(content);
        gCmdType = -1;

    }break;
    case 15://head
    {//00c800c8
        uint8_t cook[4] = {0};
        cook[0] = static_cast<uint>(data.at(0));
        cook[1] = static_cast<uint>(data.at(1));
        cook[2] = static_cast<uint>(data.at(2));
        cook[3] = static_cast<uint>(data.at(3));

        uint16_t head_val = (cook[0]<<8) + cook[1];

        //uint16_t key_val =  (cook[2]<<8) + cook[3];
        QString content = "刷头阈值:" + QString::number(head_val, 10);

        ui->DecodplainTextEdit->appendPlainText(content);
        gCmdType = -1;
    }break;
    case 19://key&head
    {//00c800c8

        uint8_t cook[4] = {0};
        cook[0] = static_cast<uint>(data.at(0));
        cook[1] = static_cast<uint>(data.at(1));
        cook[2] = static_cast<uint>(data.at(2));
        cook[3] = static_cast<uint>(data.at(3));

        uint16_t head_val = (cook[0]<<8) + cook[1];

        uint16_t key_val =  (cook[2]<<8) + cook[3];

        QString content = "刷头阈值: " + QString::number(head_val, 10)
            + " 按键阈值: " + QString::number(key_val, 10);

        ui->DecodplainTextEdit->appendPlainText(content);
        gCmdType = -1;
    }break;
    default:
        break;
    }
}
/*
 * 函数功能：定义窗口关闭时弹出的提示窗口的操作
 */
void MainWindow::closeEvent(QCloseEvent *e)
{
    Q_UNUSED(e);
    qDebug() << "exist!";

    // 保存设置
    gSetting->setValue("LastSelectSerialPort", ui->cboPortName->currentText());
    gSetting->setValue("LastSelectSerialBaud", ui->cboBaudrate->currentText());
}
/*
 * 函数功能：根据定时器ID执行对应的逻辑
 */
void MainWindow::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == gSerialPortTimer)
    {
        if(!gSerialSwitchFlg)
            initSerialPort();
    }
    else if(event->timerId() == gSendDataTimer)
    {
        if(gSerialSwitchFlg)
        {
            gSerialPort->write(ui->SendplainTextEdit->toPlainText().toUtf8());
        }
    }
}
/*
 * 函数功能：打开串口的按键功能
 */
void MainWindow::on_btnOpenPort_clicked()
{
    if(!gSerialSwitchFlg) // 串口是关闭的
    {
        gSerialPort = new QSerialPort();

        gSerialPort->setPortName(ui->cboPortName->currentText());

        gSerialPort->setBaudRate((QSerialPort::BaudRate)ui->cboBaudrate->currentData().toInt());//波特率

        gSerialPort->setDataBits((QSerialPort::DataBits)ui->cboDataBit->currentData().toInt());//数据位

        gSerialPort->setParity((QSerialPort::Parity)ui->cboParity->currentData().toInt());//奇偶校验

        gSerialPort->setStopBits((QSerialPort::StopBits)ui->cboStopBit->currentData().toInt());//停止位

        gSerialPort->setFlowControl((QSerialPort::FlowControl)ui->cboFlowContral->currentData().toInt());//控制位

        gSerialPort->open(QIODevice::ReadWrite);//读写方式打开

        connect(gSerialPort, SIGNAL(readyRead()), \
                this, SLOT(receiveData()), Qt::DirectConnection);

        gSerialSwitchFlg = true;

        ui->btnOpenPort->setText(QStringLiteral("关闭串口"));

        ui->groupBox->setDisabled(true);
        ui->btnSend->setDisabled(false);
    }
    else
    {
        gSerialPort->close();

        gSerialSwitchFlg = false;

        ui->btnOpenPort->setText(QStringLiteral("打开串口"));

        ui->groupBox->setDisabled(false);
        ui->btnSend->setDisabled(true);
    }
}
/*
 * 函数功能：发送串口数据的按键功能
 */
void MainWindow::on_btnSend_clicked()
{
    QString strSend = ui->SendplainTextEdit->toPlainText();

    QByteArray arr = strSend.toUtf8();

    gSerialPort->write(arr);
}
/*
 * 函数功能：定时发送状态改变
 */
void MainWindow::on_checkBox_stateChanged(int arg1)
{
    qDebug() << "state:" << arg1;
    if(arg1 == 2)
    {
        gSendDataTimer = startTimer(ui->lineEdit->text().toInt(), Qt::CoarseTimer);
        ui->lineEdit->setDisabled(true);
    }
    else
    {
        killTimer(gSendDataTimer);
        ui->lineEdit->setDisabled(false);
    }
}

/*
 * 发送数据的接口
 * */
void MainWindow::SendSerialMsg(QByteArray arr)
{
    ui->SendplainTextEdit->appendPlainText(arr.toHex());

    gSerialPort->write(arr);
}

void MainWindow::on_pushButton_0_clicked()
{
    // 系统复位
    uint8_t ch[3] = {0x5a, 0x00, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 0;

    SendSerialMsg(byte);
}


void MainWindow::on_pushButton_1_clicked()
{
    // 一档参数
    QString angle = ui->lineEdit_1_1->text();
    QString minHz = ui->lineEdit_1_2->text();
    QString maxHz = ui->lineEdit_1_3->text();

    bool ok;
    int angle_int = angle.toInt(&ok);
    int minHz_int = minHz.toInt(&ok);
    int maxHz_int = maxHz.toInt(&ok);

    if (ok) {
        qDebug() << "转换成功，整数为:" << angle_int;
    } else {
        qDebug() << "转换失败";
    }

    // 设置刷头过压阈值      1     8     5Hz     300Hz
    uint8_t ch[7] = {0x5a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d};

    ch[2] = (uint8_t)angle_int;
    ch[3] = (uint8_t)minHz_int;
    ch[4] = (uint8_t)(maxHz_int>>8)&0x00ff;
    ch[5] = (uint8_t)maxHz_int&0x00ff;

    QByteArray byte;
    byte = QByteArray((char*)ch,(7));

    gCmdType = 1;

    SendSerialMsg(byte);
}


void MainWindow::on_pushButton_2_clicked()
{
    // 二档参数
    QString angle = ui->lineEdit_2_1->text();
    QString minHz = ui->lineEdit_2_2->text();
    QString maxHz = ui->lineEdit_2_3->text();

    bool ok;
    int angle_int = angle.toInt(&ok);
    int minHz_int = minHz.toInt(&ok);
    int maxHz_int = maxHz.toInt(&ok);

    if (ok) {
        qDebug() << "转换成功，整数为:" << angle_int;
    } else {
        qDebug() << "转换失败";
    }

    // 设置刷头过压阈值      2     8     5Hz     300Hz
    uint8_t ch[7] = {0x5a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0d};

    ch[2] = (uint8_t)angle_int;
    ch[3] = (uint8_t)minHz_int;
    ch[4] = (uint8_t)(maxHz_int>>8)&0x00ff;
    ch[5] = (uint8_t)maxHz_int&0x00ff;

    QByteArray byte;
    byte = QByteArray((char*)ch,(7));

    gCmdType = 2;

    SendSerialMsg(byte);
}


void MainWindow::on_pushButton_3_clicked()
{
    // 三档参数
    QString angle = ui->lineEdit_3_1->text();
    QString minHz = ui->lineEdit_3_2->text();
    QString maxHz = ui->lineEdit_3_3->text();

    bool ok;
    int angle_int = angle.toInt(&ok);
    int minHz_int = minHz.toInt(&ok);
    int maxHz_int = maxHz.toInt(&ok);

    if (ok) {
        qDebug() << "转换成功，整数为:" << angle_int;
    } else {
        qDebug() << "转换失败";
    }

    // 设置刷头过压阈值      3     8     5Hz     300Hz
    uint8_t ch[7] = {0x5a, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0d};

    ch[2] = (uint8_t)angle_int;
    ch[3] = (uint8_t)minHz_int;
    ch[4] = (uint8_t)(maxHz_int>>8)&0x00ff;
    ch[5] = (uint8_t)maxHz_int&0x00ff;

    QByteArray byte;
    byte = QByteArray((char*)ch,(7));

    gCmdType = 3;

    SendSerialMsg(byte);
}


void MainWindow::on_pushButton_4_clicked()
{
    // 读NDT版本
    uint8_t ch[3] = {0x5a, 0x04, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 4;

    SendSerialMsg(byte);
}


void MainWindow::on_pushButton_5_clicked()
{
    // 读ADC、NTC
    uint8_t ch[3] = {0x5a, 0x05, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 5;

    SendSerialMsg(byte);
}


void MainWindow::on_pushButton_6_clicked()
{
    // 电机校准
    QString input = ui->lineEdit_6->text();

    bool ok;
    int number = input.toInt(&ok);

    if (ok) {
        qDebug() << "转换成功，整数为:" << number;
    } else {
        qDebug() << "转换失败";
    }

    // 设置刷头过压阈值      6
    uint8_t ch[5] = {0x5a, 0x06, 0x00, 0x00, 0x0d};

    ch[2] = (uint8_t)(number>>8)&0x00ff;
    ch[3] = (uint8_t)number&0x00ff;

    QByteArray byte;
    byte = QByteArray((char*)ch,(5));

    gCmdType = 6;

    SendSerialMsg(byte);
}


void MainWindow::on_pushButton_7_clicked()
{
    // 关闭电源
    uint8_t ch[3] = {0x5a, 0x07, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 7;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_8_clicked()
{
    // 单击
    uint8_t ch[3] = {0x5a, 0x08, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 8;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_9_clicked()
{
    // 双击
    uint8_t ch[3] = {0x5a, 0x09, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 9;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_A_clicked()
{
    // 获取KEY             ‘A’
    uint8_t ch[3] = {0x5a, 0x41, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 10;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_B_clicked()
{
    // 上报压力数据         ‘B’
    uint8_t ch[3] = {0x5a, 0x42, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 11;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_C_clicked()
{
    // 上报三轴数据         ‘C’
    uint8_t ch[3] = {0x5a, 0x43, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 12;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_D_clicked()
{
    // 清除绑定信息        ‘D’
    uint8_t ch[3] = {0x5a, 0x44, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 13;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_E_clicked()
{
    QString input = ui->lineEdit_E->text();

    bool ok;
    int number = input.toInt(&ok);

    if (ok) {
        qDebug() << "转换成功，整数为:" << number;
    } else {
        qDebug() << "转换失败";
    }

    // 设置按键阈值        ‘E’
    uint8_t ch[5] = {0x5a, 0x45, 0x00, 0x00, 0x0d};

    ch[2] = (uint8_t)(number>>8)&0x00ff;
    ch[3] = (uint8_t)number&0x00ff;


    QByteArray byte;
    byte = QByteArray((char*)ch,(5));

    gCmdType = 14;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_F_clicked()
{
    QString input = ui->lineEdit_F->text();

    bool ok;
    int number = input.toInt(&ok);

    if (ok) {
        qDebug() << "转换成功，整数为:" << number;
    } else {
        qDebug() << "转换失败";
    }

    // 设置刷头过压阈值      ‘F’
    uint8_t ch[5] = {0x5a, 0x46, 0x00, 0x00, 0x0d};

    ch[2] = (uint8_t)(number>>8)&0x00ff;
    ch[3] = (uint8_t)number&0x00ff;

    QByteArray byte;
    byte = QByteArray((char*)ch,(5));

    gCmdType = 15;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_G_clicked()
{
    // NDT归零             ‘G’
    uint8_t ch[3] = {0x5a, 0x47, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 16;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_H_clicked()
{
    // 设置1分开关测试模式  ‘H’
    uint8_t ch[3] = {0x5a, 0x48, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 17;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_I_clicked()
{
    // 设置长时间运行测试模式  ‘I’
    uint8_t ch[3] = {0x5a, 0x49, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 18;

    SendSerialMsg(byte);
}

void MainWindow::on_pushButton_J_clicked()
{
    // 读取阈值             ‘J’
    uint8_t ch[3] = {0x5a, 0x4A, 0x0d};

    QByteArray byte;
    byte = QByteArray((char*)ch,(3));

    gCmdType = 19;

    SendSerialMsg(byte);
}

